<!DOCTYPE html>
<html lang="zh-cn">
  <head>
    <meta charset="UTF-8">
    <title>Sucha's Blog - Archive for May, 2021</title>
    <meta name="generator" content="MarkdownProjectCompositor.lua">
    <meta name="author" content="Sucha">
    <meta name="keywords" content="suchang, programming, Linux, Lua">
    <meta name="description" content="Sucha's blog">
    <link rel="shortcut icon" href="../images/ico.png">
    <link rel="stylesheet" type="text/css" href="../styles/blog.css">
    <link rel="stylesheet" type="text/css" href="../styles/prism.min.css">
    <style id="site_theme"></style>
  </head>
  <body>
    <div id="body">
      <div id="text">
	   <!-- Page published by cmark-gfm begins here --><h1>Sucha's Blog ~ Archive for May, 2021</h1>
<p><a id="p0"></a></p>
<div class="date">21年5月24日 周一 22:10</div>
<h2>编写 VSCode Extension</h2>
<p>如果只是搭一个框架，VSCode Extension 的编写没有想象中那么无从入手，照着文档 <a href="https://www.cnblogs.com/liuxianan/p/vscode-plugin-overview.html">VSCode插件开发全攻略</a> 一步一步往下学就是了。</p>
<p>其实我的要求有 2 个</p>
<ul>
<li>语法高亮（syntax highlight）</li>
<li>侧边栏的大纲（outline）</li>
</ul>
<p>至于 language server 的支持，自然是不敢想的。</p>
<h3>语法高亮</h3>
<p>先说语法高亮吧，用不到 typescript 编程，只需要会正则就好，但是这个正则的规则，是跟 TextMate 一样的，<a href="https://macromates.com/manual/en/regular_expressions">文档在这里</a>。</p>
<p>这个正则默认是行匹配的，不会跨行，如果需要跨行，就需要设置 begin、end capture，另外，这个正则匹配，在设置的时候，就需要指定<a href="https://macromates.com/manual/en/language_grammars">高亮颜色</a>，偏偏 VSCode 提供的几种高亮颜色其实不怎么够用，我是想抄 EmmyLua 的一些高亮，比如全局变量的高亮，没学会人家是怎么搞的。</p>
<p>一些实践来的经验：</p>
<ul>
<li>多个匹配的话，后面的匹配会覆盖前面的匹配，颜色覆盖</li>
<li>默认是包含匹配，如果不想包含，将需要匹配的放在前面、后面，用 (?&lt;=CAPTURE)、(?=CAPTURE) 包起来</li>
<li>在支持跨行的 begin、end 匹配中，end 匹配可以用上 begin 匹配到的，比如下面这个可以匹配 Lua 的长字符串，比如 [==[ ANY THING ]==]，= 的个数是对称的</li>
</ul>
<pre><code class="language-json">&quot;strings_long&quot;: {
	&quot;name&quot;: &quot;string.quoted.single.name&quot;,
	&quot;begin&quot;: &quot;\\[(=*)\\[&quot;,
	&quot;end&quot;: &quot;\\]\\1\\]&quot;,
	&quot;patterns&quot;: [
		{
			&quot;name&quot;: &quot;constant.character.escape.name&quot;,
			&quot;match&quot;: &quot;\\\\.&quot;
		}
	]
}
</code></pre>
<h3>侧边栏大纲</h3>
<p>这个需要 typescript 编程了，我的 typescript 小学生水平都可以搞出来 outline，想必是不难的。</p>
<p>先吐槽一下，typescript 是要编译成 javascript 才能用的，另外有引入库的话，记得 npm install，否则会像我一样，浪费了大量的时间在这些基础上面。</p>
<p>outline 其实已经是 language server 的范畴了，只不过我们简单处理，将这个抽象借口部署在本地，就是简单的文本处理就好。</p>
<p>不贴代码了，反正可以在网上找到大量的的例子，比如一个行处理，split 空格拿到 token 关键字的 LS，其实不堪用，但是我是没办法，暂时先这么用着了，毕竟海没学会更好的处理方法。</p>
<p>然后呢，最外层的循环用的是变量 i，我是刚开始不小心，里面一层小循环也用变量 i 了，然后这个 typescript 停不下来了，也是无语，没有语法 scope 的吗，难过。</p>
<p>分析 token 语法的结构，是提供给 VSCode 一个带层次的 node 列表，首层是 outline 第一级，如果需要二级的画，比如 class node 里面再塞入 funciton、property 之类的，就是在这个一级 node 的 children 列表里面塞入 node，VSCode 就会帮你将这个 outline 画出来。</p>
<p>对了，这些 node 需要指定类型，比如是 class，还是 function，还是 field，其实还有很多，property，namescope 之类的，但是实话说，只有前面这 3 个是比较好看的，其他的应该是我比较少见，不明白这些个 icon 是想干嘛。</p>
<p>有了上面这些基础，我也终于理解了好些 Lua extension 为何只用上面这 3 个 outline 类型了，另外，我还知道了为何这些 Lua extension 列出了一大堆 local 变量，明明更重要的应该是全局变量呀。</p>
<p>有个坑必须要说一下。</p>
<p>不晓得是不是 outline 默认了一个 node 就是一行的原因，同一行塞入多个 node，会造成接下来的行拿不到内容，我猜测是我小学生水平的 typescript 哪里搞错了，但具体到底是哪里，目前无从知晓。</p>
<p>先这样吧。</p>
<div class="category"><a href="CategoryProgramming.html">CategoryProgramming</a> / <a href="2021-05.html#p0">Permalink</a> / <a href="https://github.com/lalawue/homepage/discussions/categories/blog" target="_blank">Discussion</a></div>
<!-- Page published by cmark-gfm ends here -->
  <div id="foot">2004-<script>var d = new
	Date();document.write(d.getFullYear())</script> &copy;
	Sucha. Powered by MarkdownProjectCompositor.
  </div>
  </div><!-- text -->
  <div id="sidebar">
  </div><!-- sidebar -->
  <script src="../js/prism.min.js" async="async"></script>
  <script src="../js/blog_sidebar.js"></script>
  </div> <!-- body -->
</body>
</html>